package com.jtcl.netty.config;

import com.jtcl.netty.service.MessageService;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Sharable
@Slf4j
public class ServerHandler extends SimpleChannelInboundHandler<Object> {

    private static Map<String, String> msgMap = new ConcurrentHashMap<String, String>();

    @Autowired
    private MessageService messageService;

    /**
     * 读取客户端信息（分批次）
     *
     * @param ctx
     * @param msg 消息内容
     * @return void
     * @author 施锦庭
     * @since 2021-02-24 9:53
     **/
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        String id = ctx.channel().id().asLongText();
        if (msgMap.containsKey(id)) {
            msgMap.put(id, msgMap.get(id) + msg.toString());
        } else {
            msgMap.put(id, msg.toString());
        }
    }

    /**
     * 完整读取客户端过来的数据
     *
     * @param ctx
     * @return void
     * @author 施锦庭
     * @since 2021-02-24 9:57
     **/
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        String msg = msgMap.get(ctx.channel().id().asLongText());
        log.info("收到来自{}的报文：{}", ctx.channel().remoteAddress().toString(), msg);
        msgMap.remove(ctx.channel().id().asLongText());
        //解析处理操作
        messageService.unpack(msg, ctx.channel());
        log.info("来自{}的数据处理完毕", ctx.channel().remoteAddress().toString());
    }

    /**
     * 通道激活时自动回调，此时客户端与服务端建立了通信通道并且可以传输数据
     *
     * @param ctx
     * @return void
     * @author 施锦庭
     * @since 2021-02-24 9:54
     **/
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("{}通道已激活！ ", ctx.channel().remoteAddress().toString());
    }

    /**
     * 通道关闭第一阶段，此时通道已不可传输数据
     *
     * @param ctx
     * @return void
     * @author 施锦庭
     * @since 2021-02-24 9:55
     **/
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        messageService.clientOffline(ctx.channel());
        log.info("{}通道已关闭！ ", ctx.channel().remoteAddress().toString());

    }

    /**
     * 异常捕获
     *
     * @param ctx
     * @param cause
     * @return void
     * @author 施锦庭
     * @since 2021-02-24 9:59
     **/
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
        log.error("{}的客户端异常信息：{} ", ctx.channel().remoteAddress().toString(), cause.getMessage(),cause);
        messageService.exceptionCaught(cause);
    }

}